package com.javastudy.liuhouse.lambda.stream;

import org.junit.Test;

import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class AllFucntionStream {
    /*
    在 Java 的 Stream API 中，聚合方法（也称为终端操作）是指对流中的元素进行最终计算或处理的方法。
    这些方法会触发流的执行，并返回一个非流的结果（如一个值、一个集合或一个副作用）。
    常见的聚合方法包括 collect、reduce、forEach、count、min、max 等。
    *
     */
    @Test
    public void testCollect(){
        /*
         * 常用的收集器
         * Collectors.toList() : 收集到List
         * Collectors.toSet() : 收集到 Set
         * Collectors.toMap() : 收集到 Map
         * Collectors.joining():将字符串流连接成一个字符串
         */
        List<String> list = Arrays.asList("a", "b", "c");
        //收集到 List
        //List<String> result = list.stream().collect(Collectors.toList());
        //System.out.println(result);
        String collect = list.stream().collect(Collectors.joining("|"));
        System.out.println(collect);
    }

    //2.reduce
    //将流中的元素通过某种规则组和起来,返回一个单一的值
    @Test
    public void testReduce() {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
        Integer sum = numbers.stream()
                .reduce(0, (a, b) -> a + b);//计算总和
        System.out.println(sum);

    }

    //ForEach
    @Test
    public void testForeach(){
        //对流中的每个元素执行一个操作（通常是一个副作用操作，如打印）。
        //forEach 是一个终端操作，通常用于执行副作用操作。
        //如果需要对流中的元素进行并行处理，可以使用 forEachOrdered 来保证顺序。
        List<String> list = Arrays.asList("a", "b", "c");
        list.stream().forEach(System.out::println);
    }


    //count
    //返回流中元素的数量
    @Test
    public void testCount(){
        List<String> list = Arrays.asList("a" , "b" , "c");
        long count = list.stream().count();//计算元素的数量
        System.out.println(count);//输出3
    }


    //min 和 max
    //返回流中的最小值和最大值
    //min 和  max返回一个Optional，因为流可能会为空
    @Test
    public void testMinAndMax(){
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        //最小值
        Optional<Integer> min = numbers.stream().min(Integer::compareTo);
        //最大值
        Optional<Integer> max = numbers.stream().max(Integer::compareTo);
        min.ifPresent(min_value -> System.out.println(min_value));
        max.ifPresent(System.out::println);
    }



    //anyMatch、allMatch 和 noneMatch
    //用于检查流中国的元素是否满足某个条件
    @Test
    public void testMatch(){
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
        //是否有元素大于3
        boolean anyMatch = numbers.stream().anyMatch(n -> n > 3);
        System.out.println(anyMatch);

        //是否所有元素都大于0
        boolean allMatch = numbers.stream().allMatch(n -> n > 0);
        System.out.println(allMatch);

        //是否没有元素小于0
        boolean noneMatch = numbers.stream().noneMatch(n -> n < 0);
        System.out.println(noneMatch);
    }


    //7.findFirst 和 findAny
    //返回流中的第一个元素或者任意一个元素
    //注意
    //findFirst 保证流中的第一个元素
    //findAny 在并行流中可能返回任意一个元素
    @Test
    public void testFind(){
        List<String> list = Arrays.asList("a", "b", "c");
        //查找第一个元素
        Optional<String> first = list.stream().findFirst();
        System.out.println(first.get());
        //使用any 输出 : a (或b或c)
        Optional<String> any = list.stream().findAny();
        System.out.println(any.get());
    }

    //8.toArray
    //将流中的元素转化为数组
    @Test
    public void testToArray(){
        List<String> list = Arrays.asList("a", "b", "c");
        //转化为数组
        String[] array = list.stream().toArray(String[]::new);
        System.out.println(Arrays.toString(array));
    }


    //9.sum , average , summaryStatistics
    //用于数值流的聚合操作
    @Test
    public void testLiu(){
        IntStream intStream = IntStream.of(1, 2, 3, 4, 5);
        //求和 - [在这里使用了 sum() 就代表了终结]
//        int sum = intStream.sum();
        //求平均值
//        double average = intStream.average().orElse(0);
        //汇总统计
        IntSummaryStatistics intSummaryStatistics = intStream.summaryStatistics();
        System.out.println(intSummaryStatistics);

//        System.out.println(sum);

//        System.out.println(average);
    }


}
